#include "AttributeWidget.h"
#include <SEEdit/Layer/EditLayer.h>
#include <SEngine/Render/Descriptors/SceneDescriptor.h>
#include <SEEdit/Descriptors/SelectActorDescriptor.h>
#include <SEngine/Ecs/Components/AllComponents.h>
#include <SEUi/SEUi.h>
#include <SECore/Ecs/Actor.h>
#include <SEDebug/Log/Log.h>
// #include <SEUi/Widget/FileDialog/ImGuiFileDialog.h>
#include <SECore/CoreApplication.h>
#include <SEngine/Project/Project.h>
#include <SEAssets/AssetsElem.h>

// #include <ImGuiFileDialog.h>

namespace SEngine
{

    using Components = TypesLoader<
        TransformComp,
        PointLightComp,
        DirectLightComp,
        AmbientLightSphereComp,
        ModelRenderComp,
        ScriptComp,
        CameraComp,
        RigidBodyComp,
        HDRSkyboxComp,
        DynamicSkyboxComp
    >;

    AttributeWidget::AttributeWidget(EditLayer & layer)
        : Widget()
        , m_layer(layer)
    {
    }

    void AttributeWidget::BeginUpdate()
    {
    }

    void AttributeWidget::UpdateImpl(int delta)
    {
        auto selectActorDes = m_layer.GetApp().GetDescriptor<SelectActorDescriptor>();
        if (!selectActorDes || !selectActorDes->get().selectActor) {
            return;
        }
        auto & selectActor = selectActorDes->get().selectActor->get();
        ImGui::PushID("AttributeWidget");
        if (auto & uuidComp = selectActor.GetComponent<UuidComp>(); uuidComp) {
            ImGui::Text("ID: %s", uuidComp->get().uuid.c_str());
        }
        if (auto & nameComp = selectActor.GetComponent<NameComp>(); nameComp) {
            static char actorName[256] = {0};
            strcpy_s<sizeof(actorName)>(actorName, nameComp->get().name.data());
            ImGui::InputText("Name", actorName, sizeof(actorName));
            nameComp->get().name = actorName;
        }
        ShowComponentsCombo(selectActor);
        ImGui::Separator();
        ShowComponentDetail(selectActor);
        ImGui::PopID();
    }

    void AttributeWidget::EndUpdate()
    {

    }

    void AttributeWidget::ShowComponentsCombo(Actor & actor)
    {
        // auto worldDes = m_layer.GetApp().GetDescriptor<WorldDescriptor>();
        static std::string currentItem;
        if (ImGui::Button("Add")) {
            ForeachType([&](auto loader) {
                Reflect<decltype(loader)::Type> info;
                if (currentItem == info.Name()) {
                    auto & comp = actor.AddComponent<decltype(loader)::Type>();
                    Log::GetInstance().Info("Add Component {}", info.Name());
                }
            }, Components());
        }
        ImGui::SameLine();
        if (ImGui::BeginCombo("Components", currentItem.c_str())) {
            ForeachType([&](auto loader) {
                Reflect<decltype(loader)::Type> info;
                bool isSelected = (currentItem == info.Name());
                if (ImGui::Selectable(info.Name().c_str(), isSelected)) {
                    currentItem = info.Name();
                }
                if (isSelected) {
                    ImGui::SetItemDefaultFocus();
                }
            }, Components());
            ImGui::EndCombo();
        }
    }

    template<typename T>
    void ShowComponentDetailImpl(T & comp, AttributeWidget & widget) {}

    void AttributeWidget::ShowComponentDetail(Actor &actor)
    { 
        ForeachType([&](auto loader) {
            if (auto comp = actor.GetComponent<decltype(loader)::Type>(); comp) {
                ImGui::PushID((int)comp->get().Hash());
                ShowComponentDetailImpl(comp->get(), *this);
                ImGui::PopID();
            }
        }, Components());
    }
} // namespace SEngine


#include <SEEdit/Widget/ComponentsPanel.inl>
